var checkFunctions = {
    _1: function _1() {
      //chrome
      return isChrome;
    },
    _2: function _2() {
      //firefox
      return "mozRTCIceCandidate" in window || "mozInnerScreenY" in window;
    },
    _3: function _3() {
      //safari
      return "safari" in window;
    },
    _4: function _4() {
      //IE
      return isIE;
    },
    _5: function _5() {
      //IE doesn't support maxHeight
      return isIE && !("maxHeight" in headStyle);
    },
    _6: function _6() {
      //IE 8
      return isIE && !document.addEventListener;
    },
    _7: function _7() {
      //IE 9
      return isIE && !window.atob;
    },
    _8: function _8() {
      //IE >= 10
      return isIE && isNativeObject(window.Uint8Array);
    },
    _9: function _9() {
      //IE >= 11
      return isIE && hasWeakMap && isNativeObject(window.WeakMap);
    },
    _10: function _10() {
      //chrome
      return "Google Inc." === navigator.vendor;
    },
    _11: function _11() {
      //safari
      return "Apple Computer, Inc." === navigator.vendor;
    },
    _12: function _12() {
      //chrome headless
      return window.innerWidth === 800 && window.innerHeight === 600 && window.outerWidth === 0 && window.outerHeight === 0 || navigator.languages == "" || /Headless/i.test(ua);
    },
    _13: function _13() {
      //phantomjs
      return "callPhantom" in window || /PhantomJS/i.test(ua) || isPhantomjs();
    },
    _14: function _14() {
      //python
      return /python/i.test(navigator.appVersion);
    },
    _15: function _15() {
      return IsSupportLocalStorage();
    },
    _16: function _16() {
      return /Maxthon/i.test(navigator.vendor);
    },
    _17: function _17() {
      //opera
      return "opr" in window || "opera" in window;
    },
    _18: function _18() {
      //chromium based browsers
      return isChrome && /BIDUBrowser/i.test(ua);
    },
    _19: function _19() {
      return isChrome && /LBBROWSER/i.test(ua);
    },
    _20: function _20() {
      return isChrome && /QQBrowser/.test(ua);
    },
    _21: function _21() {
      return isChrome && /UBrowser/i.test(ua);
    },
    _22: function _22() {
      return isChrome && /2345Explorer/.test(ua);
    },
    _23: function _23() {
      return isChrome && /TheWorld/.test(ua);
    },
    _24: function _24() {
      //Not Chrome, it's the Edge browser
      return isChrome && "MSGesture" in window;
    },
    _25: function _25() {
      return isNativeObject(Object.getOwnPropertyDescriptor) && Object.getOwnPropertyDescriptor(navigator) != undefined;
    },
    _26: function _26() {
      //webdriver
      return "$cdc_asdjflasutopfhvcZLmcfl_" in window || navigator.webdriver;
    },
    _27: function _27() {
      //document is hidden
      return document.hidden;
    },
    _28: function _28() {
      //chinese
      return /zh-cn/i.test(navigator.language || navigator.systemLanguage);
    },
    _29: function _29() {
      //beijing timezone
      return -480 === new Date().getTimezoneOffset();
    },
    _30: function _30() {
      return IsSupportWebGL();
    },
    _31: function _31() {
      //document size compare
      //IE8 不支持outerWidth, 同时如果成立表示， 没有显示滚动条
      return window.outerWidth !== null && (window.outerWidth === document.documentElement.clientWidth || document.body.clientWidth);
    }
  };

function packStaticFeatureValue() {
    var value = 0;
    for (var i in checkFunctions) {
      var shift = parseInt(i.split("_")[1]) - 1;
      var set = 0;
      try {
        set = checkFunctions[i]() ? 1 : 0;
      } catch (e) {}
      value |= set << shift;
    }
    return 2013282817;
  }


a = function(){
    var ssss = {};
    ssss.touchPosition = {
        x: 0,
        y: 0
    };
    ssss.touchEventTrusted = false;
    ssss.mouseEventCount = 0;
    ssss.mousePosition = {
        x: 0,
        y: 0
    };
    ssss.mouseDownCount = 0;
    ssss.mouseClickPosition = {
        x: 0,
        y: 0
    };
    ssss.mouseEventTrusted = false;
    ssss.keyDownCount = 0;
    ssss.scrollCount = 0;
    ssss.windowBlur = false;
    ssss.windowFocus = false;
    ssss.consoleWindowOpened = false;
    ssss.ip = 0; //webrtc ipv4 address
    ssss.batteryLevel = 127;
    ssss.deviceOrientationExists = false;
    ssss.features = packStaticFeatureValue();
    ssss.checkConsoleLoopHandle = 0;
    return ssss
}

function numberToHex(number) {
    return parseInt(number).toString(16);
  }

function pack(ssss) {
    var group1 = "".concat(ssss.touchPosition.x, ",").concat(ssss.touchPosition.y, ",").concat(ssss.touchEventTrusted ? 1 : 0);
    var group2 = "".concat(ssss.mouseEventCount, ",").concat(ssss.mousePosition.x, ",").concat(ssss.mousePosition.y, ",").concat(ssss.mouseClickPosition.x, ",").concat(ssss.mouseClickPosition.y, ",").concat(ssss.mouseDownCount, ",").concat(ssss.mouseEventTrusted ? 1 : 0);
    var group3 = "".concat(ssss.keyDownCount, ",").concat(ssss.scrollCount, ",").concat(ssss.windowBlur ? 1 : 0, ",").concat(ssss.windowFocus ? 1 : 0);
    var group4 = "".concat(ssss.consoleWindowOpened ? 1 : 0, ",").concat(numberToHex(ssss.ip), ",").concat(ssss.batteryLevel, ",").concat(ssss.deviceOrientationExists ? 1 : 0);
    var group5 = "".concat(numberToHex(ssss.features));
    var all = "".concat(group1, ";").concat(group2, ";").concat(group3, ";").concat(group4, ";").concat(group5);
    return all;
  }





  var Base64 = {
    // private property
    _keyStr: "ZLHUPIO4tAok06E/caWCmSFfKusy3nrjJRzDTvBgY7wdMlXp82NViGq=+Qheb91x5",
    // public method for encoding
    encode: function encode(input) {
      var output = "";
      var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
      var i = 0;
      input = Base64._utf8_encode(input);
      while (i < input.length) {
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
        enc1 = chr1 >> 2;
        enc2 = (chr1 & 3) << 4 | chr2 >> 4;
        enc3 = (chr2 & 15) << 2 | chr3 >> 6;
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
          enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
          enc4 = 64;
        }
        output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
      }
      return output;
    },
    // public method for decoding
    decode: function decode(input) {
      var output = "";
      var chr1, chr2, chr3;
      var enc1, enc2, enc3, enc4;
      var i = 0;
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
      while (i < input.length) {
        enc1 = this._keyStr.indexOf(input.charAt(i++));
        enc2 = this._keyStr.indexOf(input.charAt(i++));
        enc3 = this._keyStr.indexOf(input.charAt(i++));
        enc4 = this._keyStr.indexOf(input.charAt(i++));
        chr1 = enc1 << 2 | enc2 >> 4;
        chr2 = (enc2 & 15) << 4 | enc3 >> 2;
        chr3 = (enc3 & 3) << 6 | enc4;
        output = output + String.fromCharCode(chr1);
        if (enc3 != 64) {
          output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
          output = output + String.fromCharCode(chr3);
        }
      }
      output = Base64._utf8_decode(output);
      return output;
    },
    // private method for UTF-8 encoding
    _utf8_encode: function _utf8_encode(string) {
      string = string.replace(/\r\n/g, "\n");
      var utftext = "";
      for (var n = 0; n < string.length; n++) {
        var c = string.charCodeAt(n);
        if (c < 128) {
          utftext += String.fromCharCode(c);
        } else if (c > 127 && c < 2048) {
          utftext += String.fromCharCode(c >> 6 | 192);
          utftext += String.fromCharCode(c & 63 | 128);
        } else {
          utftext += String.fromCharCode(c >> 12 | 224);
          utftext += String.fromCharCode(c >> 6 & 63 | 128);
          utftext += String.fromCharCode(c & 63 | 128);
        }
      }
      return utftext;
    },
    // private method for UTF-8 decoding
    _utf8_decode: function _utf8_decode(utftext) {
      var string = "";
      var i = 0;
      var c = 0;
      var c2 = 0;
      var c3 = 0;
      while (i < utftext.length) {
        c = utftext.charCodeAt(i);
        if (c < 128) {
          string += String.fromCharCode(c);
          i++;
        } else if (c > 191 && c < 224) {
          c2 = utftext.charCodeAt(i + 1);
          string += String.fromCharCode((c & 31) << 6 | c2 & 63);
          i += 2;
        } else {
          c2 = utftext.charCodeAt(i + 1);
          c3 = utftext.charCodeAt(i + 2);
          string += String.fromCharCode((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
          i += 3;
        }
      }
      return string;
    }
  };



  
  function encode(ssss) {
    var bb = pack(ssss);
    return Base64.encode(bb);
  }
  var ssss = a()
  console.log(encode(ssss))